/** 方法装饰器 **/

/** 不带参数的
 * targetClassPrototype: [RoleService.prototype]
 * methodname 方法名
 * methodDecri：数据属性 **/
function MyMethodDecorator(targetClassPrototype: any, methodname: string, methodDecri: PropertyDescriptor) {
  console.log('targetClassPrototype:', targetClassPrototype) // { DistribRoles: [Function (anonymous)] }
  console.log('methodname:', methodname) //  DistribRoles
  console.log('数据属性:', methodDecri) 
  //打印的数据属性 {
  //   value: [Function (anonymous)],
  //   writable: true,
  //   enumerable: true,
  //   configurable: true
  // }
  methodDecri.value() // 执行被装饰器修饰的方法DistribRoles【输出：分配角色...】
}

// 带参数的
function MyMethodDecorator2(metodPath: string) {
  return function(targetClassPrototype: any, methodname: string, methodDecri: PropertyDescriptor) {
    console.log('传参', metodPath)
    console.log('targetClassPrototype:', targetClassPrototype) // { DistribRoles: [Function (anonymous)] }
    console.log('methodname:', methodname) //  DistribRoles
    console.log('数据属性:', methodDecri) 
    //打印的数据属性 {
    //   value: [Function (anonymous)],
    //   writable: true,
    //   enumerable: true,
    //   configurable: true
    // }
    methodDecri.value() // 执行被装饰器修饰的方法DistribRoles【输出：分配角色...】
  }
}

function MethodInterceptor(paramsValue: any) {
  console.log("拦截器");
  return function (targetClassPrototype: any, methodName: any,
    methodDecri: PropertyDescriptor) {

    // 先保存目标类的方法到targetMethodSave
    let targetMethodSave = methodDecri.value;

    // 1.2.让value函数建立新得函数对象空间 
    //  value建立一个新的函数后,
    // RoleService对象调用DistribRoles;会执行value指向的新函数
    //  并不会执行原来RoleService目标类中DistribRoles方法
    //  这里建立的一个新函数
    methodDecri.value = function (...args: any[]) {
      // 迭代所有参数 
      args = args.map((arg) => {
        if (typeof arg === "string") {
          // 去掉参数中的所有空格
          return arg.replace(/\s+/g, "");
        }
        return arg;
      })
      console.log('我是前置拦截做的事情') // 这里做一些前置拦截事情
      targetMethodSave.apply(this, args) // 调用原方法
      console.log('我是后置拦截做的事情') // 这里做一些后置拦截事情
    }
  }
}

class RoleService {
  public roleName:string = '管理员'
  constructor(){
    
  }

  @MyMethodDecorator
  @MyMethodDecorator2('/api/login')
  @MethodInterceptor('DistribRoles方法')
  DistribRoles(userName: string, isValid: boolean) { // 分配角色
    console.log(userName, '分配角色...')
  }
}

let role1 = new RoleService()
role1.DistribRoles('我 是管理员  ', true)